// PCG pseudo random number generator
struct Rng
{
    uint64_t state;
    uint64_t seq;
};

DECLSPEC inline uint32_t rng_rand(struct Rng* rng)
{
    uint64_t oldstate = rng->state;
    rng->state = oldstate * 6364136223846793005UL + rng->seq;
    uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u;
    uint32_t rot = oldstate >> 59u;
    return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
}

DECLSPEC inline void rng_init(struct Rng* rng, uint64_t seed, uint64_t seq)
{
    rng->state = seed;
    rng->seq = (seed + seq) * 2 + 1;

    // HACK : dirty hack for better streams
    rng_rand(rng);
    rng_rand(rng);
}

DECLSPEC inline void rng_fill_bytes(struct Rng* rng, uint8_t* bytes, size_t n)
{
    for(size_t j = 0; j < n;) {
        uint32_t num = rng_rand(rng);
        for(size_t k = 0; k < 4 && j < n; ++j, ++k) {
            bytes[j] = (num >> (k * 8)) & 0xff;
        }
    }
}